package job.manager.client.servlets;

import javax.ejb.EJB;
import javax.xml.transform.Transformer;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import job.manager.db.ec.TimeReportEB;
import job.manager.db.sb.TimeRemote;
import org.jdom.Document;
import org.jdom.Element;
import java.util.GregorianCalendar;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import job.manager.client.mb.ConnectFactory;

/**
 *  Servlet for creating and showing the timereports that are made by the reportId provided
 *  Loads a specified xsl or the standard.
 *  Parses the created xml with that xsl.
 *
 */
public class ReportTimeServlet extends HttpServlet {

    @EJB
    private TimeRemote timeBean;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * this Servlet creates a xml of the provided profileId and parses it with the
     * xsl that is provided in the parameter xsl or the standard xsl that is
     * provided in this file
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            GregorianCalendar cal = new GregorianCalendar();

            //We need a start date...
            cal.set(2008, 10, 1);

            String profileId = request.getParameter("profileId");
            
            // get the document
            Document domdoc = report(cal.getTime(), new Integer(profileId));
            // load the xslt
            String path = "WEB-INF/";
            if( request.getParameter("xsl") == null)
                path += "timeReportSheet.xsl";
            else
                path += request.getParameter("xsl").toString();

            InputStream in = request.getSession().getServletContext().getResourceAsStream(path);
            //create outputter
            org.jdom.output.DOMOutputter outputter = new org.jdom.output.DOMOutputter();
            //genereate and w3c document
            org.w3c.dom.Document domDocument;
            domDocument = outputter.output(domdoc);
            javax.xml.transform.Source xmlSource = new javax.xml.transform.dom.DOMSource(domDocument);
            //transport streams
            StreamSource xsltSource = new StreamSource(in);
            StreamResult xmlResult = new StreamResult(out);

            //Create the factory
            TransformerFactory factory = TransformerFactory.newInstance();

            Transformer transformer = factory.newTransformer(xsltSource);
            //parse out the sampled xslt/xml
            transformer.transform(xmlSource, xmlResult);

        } catch (Exception ex) {
            out.println(ex.getMessage());
        } finally {
            out.close();
        }
    }

    //the spring security bug fix
    public void problemSolver() {
        if (this.timeBean == null) {
            this.timeBean = ConnectFactory.getTimeBean();
        }
    }

    //create a jdom Doxument that can be parsed with the xsl
    public Document report(Date startDate, Integer profileId) {
        this.problemSolver(); //fix the spring bug
        //create hel calendar
        GregorianCalendar helpCal = new GregorianCalendar();
        helpCal.setTime(startDate);
        //get the week of the start date
        int week = helpCal.get(Calendar.WEEK_OF_YEAR);
        helpCal.add(Calendar.HOUR, 24 * 7);
        //create a xml create helper
        ReportTimeHelper xmlFac = new ReportTimeHelper();
        String time = new String();
        String date = new String();
        //get the timereports that the profile got
        Collection<TimeReportEB> JTR = timeBean.getTimeReportByProfileDateSorted(profileId);
        if( JTR == null ){
            return null; //if no stamps just return null
        }
        //create lists for handling the diffrent elemnts
        ArrayList<Element> dayEvents = new ArrayList<Element>();
        ArrayList<Element> day = new ArrayList<Element>();
        ArrayList<Element> weeks = new ArrayList<Element>();
        LinkedList<GregorianCalendar> ll = new LinkedList<GregorianCalendar>();
        for (TimeReportEB e : JTR) { //for each timereport start create the xml
            Date d = e.getScheduleRowId().getDateTime(); //get date
            helpCal.setTime(d); //Set time
            if (ll.isEmpty()) {
                ll.addFirst(helpCal); //create date
            }
            //collect time and date data
            int hour = helpCal.get(Calendar.HOUR_OF_DAY);
            int minute = helpCal.get(Calendar.MINUTE);
            int month = helpCal.get(Calendar.MONTH) + 1;
            int monthday = helpCal.get(Calendar.DAY_OF_MONTH);

            time = new String(hour + ":" + minute);
            date = new String(monthday + "/" + month);

            //cehck if it's the same day
            boolean sameMonth = helpCal.get(Calendar.MONTH) == ll.getFirst().get(Calendar.MONTH);
            boolean sameDay = helpCal.get(Calendar.DAY_OF_MONTH) == ll.getFirst().get(Calendar.DAY_OF_MONTH);
            if (sameMonth && sameDay) {
                dayEvents.add(xmlFac.getDayEvent(e.getScheduleRowId().getComment(), "", time));   // Ã„ndra comment ev.
                //if not the create a new day
            } else {
                day.add(xmlFac.getDay(time, dayEvents));
                dayEvents.clear();
                dayEvents.add(xmlFac.getDayEvent(e.getComment(), e.getComment(), time));
                ll.clear();
                ll.addFirst(helpCal);
            }

        }
        //when all is done add the day and create a weeklist
        day.add(xmlFac.getDay(date, dayEvents));
        weeks.add(xmlFac.getWeek(new String("" + week), day));
        return xmlFac.getWeekList(weeks);
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">

    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
